package pagination

import (
	"strconv"

	"github.com/gin-gonic/gin"
)

const (
	DefaultPage     = 1
	DefaultPageSize = 10
	MaxPageSize     = 100
)

// Params 分页参数
type Params struct {
	Page     int   `json:"page"`
	PageSize int   `json:"page_size"`
	Total    int64 `json:"total"`
}

// Result 分页结果
type Result struct {
	Items     interface{} `json:"items"`
	Page      int         `json:"page"`
	PageSize  int         `json:"page_size"`
	Total     int64       `json:"total"`
	TotalPage int64       `json:"total_page"`
}

// GetPageParams 从请求中获取分页参数
func GetPageParams(c *gin.Context) Params {
	// 获取页码，默认为1
	pageStr := c.DefaultQuery("page", "1")
	page, err := strconv.Atoi(pageStr)
	if err != nil || page < 1 {
		page = DefaultPage
	}

	// 获取每页数量，默认为10
	pageSizeStr := c.DefaultQuery("page_size", "10")
	pageSize, err := strconv.Atoi(pageSizeStr)
	if err != nil || pageSize < 1 {
		pageSize = DefaultPageSize
	}

	// 限制最大页面大小
	if pageSize > MaxPageSize {
		pageSize = MaxPageSize
	}

	return Params{
		Page:     page,
		PageSize: pageSize,
	}
}

// GetOffset 获取数据库查询的偏移量
func (p *Params) GetOffset() int {
	return (p.Page - 1) * p.PageSize
}

// GetLimit 获取数据库查询的限制数量
func (p *Params) GetLimit() int {
	return p.PageSize
}

// SetTotal 设置总数并返回是否有下一页
func (p *Params) SetTotal(total int64) {
	p.Total = total
}

// GetTotalPage 获取总页数
func (p *Params) GetTotalPage() int64 {
	if p.Total == 0 || p.PageSize == 0 {
		return 0
	}
	return (p.Total + int64(p.PageSize) - 1) / int64(p.PageSize)
}

// ToResult 转换为分页结果
func (p *Params) ToResult(items interface{}) Result {
	return Result{
		Items:     items,
		Page:      p.Page,
		PageSize:  p.PageSize,
		Total:     p.Total,
		TotalPage: p.GetTotalPage(),
	}
}